package com;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Controller
public class DataResponseController {

    //页面跳转
    //响应结果后 springMVC基于返回的结果 使用视图解析器解析 返回给客户端页面
    //默认使用转发访问 所以可以访问web-info下的资源 url地址不会改变
    //可以添加前缀redirect: 设置为重定向 无法携带数据

    //1、返回值为视图字符串
    @RequestMapping("/data1.do")
    public String data1(HttpServletRequest request){
        request.setAttribute("msg", "返回值为视图字符串");
        return "redirect:/view/data1.jsp";//会自动将结果进行视图拼接 返回给客户端
    }

    //2、返回ModelAndView设置视图
    //借助Spring功能 将对象的创建设置为参数 自动创建指定对象(可以理解为该对象交由spring管理 可以直接注入使用)
    @RequestMapping("data2.do")
    public ModelAndView data2(ModelAndView mv){
        mv.setViewName("data2");
        mv.addObject("msg", "返回ModelAndView设置视图");
        return mv;
    }

    //直接返回数据
    //直接返回字符串数据
    //使用response对象方法回写数据
    @RequestMapping("/data3.do")
    public void data3(HttpServletResponse response) throws IOException {
        PrintWriter writer = response.getWriter();
        writer.println("通过response获取输出流在页面输出数据");
    }


    //将需要返回的数据直接通过返回值返回
    @RequestMapping("/data4.do")
    @ResponseBody//告诉spring不要使用视图解析器解析
    public String data4(){
        return "通过返回值设置String直接返回数据";
    }
    //json数据是前后台进行数据交互的格式
    //本质也是字符串 可以通过拼接的形式实现
    @RequestMapping(value="/data5.do")
    @ResponseBody
    public String data5() throws IOException {
        return "{\"username\":\"zhangsan\",\"age\":18}";
    }

    //返回自定义对象
    @RequestMapping(value="/data6.do")
    @ResponseBody
    public User data6()  {
        //如下对象返回
        User user =new User(1,"zhangsan",18);
        //原本我们需要手动拼接json字符串 或者调用json工具类转换后返回
        //return "{\"id\":1,\"username\":\"zhangsan\",\"age\":18}";
        return user;//会自动使用工具类转换并返回
    }


    //返回集合对象
    @RequestMapping(value="/data7.do")
    @ResponseBody
    public List<User> data7() {
        ArrayList<User> list=new ArrayList<>();
        list.add(new User(1,"a1",1));
        list.add(new User(2,"a2",2));
        list.add(new User(3,"a3",3));
        list.add(new User(4,"a4",4));
        return list;//会自动使用工具类转换并返回
    }
    @RequestMapping("/arg1")
    @ResponseBody
    public void arg1(String name,int age){
        System.out.println(name+"|"+age);
    }
    //请求参数绑定注解
    //当请求name与形参名称不匹配时 可以通过注解进行绑定
    //value绑定的名称
    //required是否必填 (请求时如果没有携带该参数会报错)
    //defaultValue默认值 请求没有携带该数据时 使用默认值赋值 该属性定义会自动将required设置为false
    @RequestMapping("/arg2")
    @ResponseBody
    public void arg2(@RequestParam(value = "name1",required = true) String name, @RequestParam(value = "age",defaultValue = "18") int age){
        System.out.println(name+"|"+age);
    }

    //2、自定义类型参数的获取
    //在实际开发中基本参数就是基于数据库表 我们会基于orm映射创建对应的java类
    //当然我们可以直接定义多个参数 但是我们还需自己创建对象赋值
    //让spring基于参数类型自动为我们调用无参构造方法创建对象 并基于属性进行赋值
    @RequestMapping("/arg3")
    @ResponseBody
    public void arg3(User u){
        System.out.println(u);
    }
    //获取请求json格式的数据
    //底层使用jackson进行json解析后存入
    @RequestMapping("/arg4")
    @ResponseBody
    public void arg4(@RequestBody User u){
        System.out.println(u);
    }

    //3、数组类型数据获取
    //在前端页面进行多选框选择时 提交的多个数据name相同
    //这个时候如果使用单个属性接收 仅获取第一个
    //这个时候就需要使用数组类型的参数进行获取 springMVC也会自动帮我们将其存入数组
    @RequestMapping("/arg5")
    @ResponseBody
    public void arg4(String [] likes){
        System.out.println(Arrays.toString(likes));
    }

    //4、存储自定义类型数据集合类型数据的获取
    @RequestMapping("/arg6")
    @ResponseBody
    public void arg6(@RequestBody List<User> userList){
        System.out.println(userList);
    }

}

